﻿using System;
using UnityEngine;

namespace Spline
{
	// Token: 0x020003FC RID: 1020
	public class RNS
	{
		// Token: 0x0600196D RID: 6509 RVA: 0x000A42F4 File Offset: 0x000A24F4
		public void Init()
		{
			this.nodeCount = 0;
		}

		// Token: 0x0600196E RID: 6510 RVA: 0x000A4300 File Offset: 0x000A2500
		public void AddNode(Vector3 pos)
		{
			if (this.nodeCount == 0)
			{
				this.maxDistance = 0f;
			}
			else
			{
				this.node[this.nodeCount - 1].distance = this.Vector3_Length(this.node[this.nodeCount - 1].position - pos);
				this.maxDistance += this.node[this.nodeCount - 1].distance;
			}
			this.node[this.nodeCount++].position = pos;
		}

		// Token: 0x0600196F RID: 6511 RVA: 0x000A43AC File Offset: 0x000A25AC
		protected void RemoveHeadNode()
		{
			if (this.nodeCount == 0)
			{
				return;
			}
			this.maxDistance -= this.node[0].distance;
			for (int i = 0; i < this.nodeCount - 1; i++)
			{
				this.node[i] = this.node[i + 1];
			}
			this.nodeCount--;
		}

		// Token: 0x06001970 RID: 6512 RVA: 0x000A4430 File Offset: 0x000A2630
		public virtual void BuildSpline()
		{
			this.Build();
		}

		// Token: 0x06001971 RID: 6513 RVA: 0x000A4438 File Offset: 0x000A2638
		protected void Build()
		{
			for (int i = 1; i < this.nodeCount - 1; i++)
			{
				Vector3 a = Vector3.Normalize(this.node[i + 1].position - this.node[i].position);
				Vector3 b = Vector3.Normalize(this.node[i - 1].position - this.node[i].position);
				this.node[i].velocity = a - b;
				this.node[i].velocity.Normalize();
			}
			this.node[0].velocity = this.GetStartVelocity(0);
			this.node[this.nodeCount - 1].velocity = this.GetEndVelocity(this.nodeCount - 1);
		}

		// Token: 0x06001972 RID: 6514 RVA: 0x000A4528 File Offset: 0x000A2728
		protected void BuildLast()
		{
			int num = this.nodeCount - 2;
			this.node[num].velocity = Vector3.Normalize(this.node[num + 1].position - this.node[num].position) - Vector3.Normalize(this.node[num - 1].position - this.node[num].position);
			this.node[num].velocity.Normalize();
			this.node[this.nodeCount - 1].velocity = this.GetEndVelocity(this.nodeCount - 1);
		}

		// Token: 0x06001973 RID: 6515 RVA: 0x000A45EC File Offset: 0x000A27EC
		public virtual float RenewMove(Vector3 pos, float time)
		{
			int num;
			int num2;
			float rate;
			this.TimeState(time, out num, out num2, out rate);
			this.RemoveHeadNode();
			this.AddNode(pos);
			this.BuildLast();
			return this.GetTime(num - 1, rate);
		}

		// Token: 0x06001974 RID: 6516 RVA: 0x000A4624 File Offset: 0x000A2824
		public Vector3 GetPosition(float time)
		{
			if (time <= 0f)
			{
				return this.node[0].position;
			}
			if (time >= 1f)
			{
				return this.node[this.nodeCount - 1].position;
			}
			float num = time * this.maxDistance;
			float num2 = 0f;
			int num3 = 0;
			while (num3 < this.nodeCount && num2 + this.node[num3].distance < num)
			{
				num2 += this.node[num3].distance;
				num3++;
			}
			if (num3 == this.nodeCount)
			{
				num3 = this.nodeCount - 1;
			}
			float num4 = num - num2;
			num4 /= this.node[num3].distance;
			Vector3 startVel = this.node[num3].velocity * this.node[num3].distance;
			Vector3 endVel = this.node[num3 + 1].velocity * this.node[num3].distance;
			return RNS.GetPositionOnCubic(this.node[num3].position, startVel, this.node[num3 + 1].position, endVel, num4);
		}

		// Token: 0x06001975 RID: 6517 RVA: 0x000A4774 File Offset: 0x000A2974
		protected void TimeState(float time, out int prevNo, out int nextNo, out float rate)
		{
			float num = time * this.maxDistance;
			float num2 = 0f;
			int num3 = 0;
			while (num3 < this.nodeCount && num2 + this.node[num3].distance < num)
			{
				num2 += this.node[num3].distance;
				num3++;
			}
			if (num3 == this.nodeCount)
			{
				num3 = this.nodeCount - 1;
			}
			float num4 = num - num2;
			num4 /= this.node[num3].distance;
			prevNo = num3;
			nextNo = num3 + 1;
			rate = num4;
		}

		// Token: 0x06001976 RID: 6518 RVA: 0x000A4810 File Offset: 0x000A2A10
		protected float GetTime(int prevNo, float rate)
		{
			float num = 0f;
			for (int i = 0; i < prevNo; i++)
			{
				num += this.node[i].distance;
			}
			num += this.node[prevNo].distance * rate;
			return num / this.maxDistance;
		}

		// Token: 0x06001977 RID: 6519 RVA: 0x000A4868 File Offset: 0x000A2A68
		protected Vector3 GetStartVelocity(int index)
		{
			if (this.node[index].distance == 0f)
			{
				return Vector3.zero;
			}
			Vector3 a = 3f * (this.node[index + 1].position - this.node[index].position) / this.node[index].distance;
			return (a - this.node[index + 1].velocity) * 0.5f;
		}

		// Token: 0x06001978 RID: 6520 RVA: 0x000A4904 File Offset: 0x000A2B04
		protected Vector3 GetEndVelocity(int index)
		{
			if (this.node[index - 1].distance == 0f)
			{
				return Vector3.zero;
			}
			Vector3 a = 3f * (this.node[index].position - this.node[index - 1].position) / this.node[index - 1].distance;
			return (a - this.node[index - 1].velocity) * 0.5f;
		}

		// Token: 0x06001979 RID: 6521 RVA: 0x000A49A4 File Offset: 0x000A2BA4
		protected static Vector3 GetPositionOnCubic(Vector3 startPos, Vector3 startVel, Vector3 endPos, Vector3 endVel, float time)
		{
			Matrix4x4 lhs = default(Matrix4x4);
			lhs.m00 = 2f;
			lhs.m01 = -2f;
			lhs.m02 = 1f;
			lhs.m03 = 1f;
			lhs.m10 = -3f;
			lhs.m11 = 3f;
			lhs.m12 = -2f;
			lhs.m13 = -1f;
			lhs.m20 = 0f;
			lhs.m21 = 0f;
			lhs.m22 = 1f;
			lhs.m23 = 0f;
			lhs.m30 = 1f;
			lhs.m31 = 0f;
			lhs.m32 = 0f;
			lhs.m33 = 0f;
			Matrix4x4 rhs = new Matrix4x4
			{
				m00 = startPos.x,
				m01 = startPos.y,
				m02 = startPos.z,
				m03 = 1f,
				m10 = endPos.x,
				m11 = endPos.y,
				m12 = endPos.z,
				m13 = 1f,
				m20 = startVel.x,
				m21 = startVel.y,
				m22 = startVel.z,
				m23 = 1f,
				m30 = endVel.x,
				m31 = endVel.y,
				m32 = endVel.z,
				m33 = 1f
			};
			rhs = lhs * rhs;
			Vector4 v = new Vector4(time * time * time, time * time, time, 1f);
			Matrix4x4 identity = Matrix4x4.identity;
			identity.SetRow(3, v);
			return (identity * rhs).GetRow(3);
		}

		// Token: 0x0600197A RID: 6522 RVA: 0x000A4BA0 File Offset: 0x000A2DA0
		private float Vector3_Length(Vector3 v)
		{
			return v.magnitude;
		}

		// Token: 0x04001CB8 RID: 7352
		public RNS.splineData[] node = new RNS.splineData[100];

		// Token: 0x04001CB9 RID: 7353
		public float maxDistance;

		// Token: 0x04001CBA RID: 7354
		public int nodeCount;

		// Token: 0x020003FD RID: 1021
		public struct splineData
		{
			// Token: 0x04001CBB RID: 7355
			public Vector3 position;

			// Token: 0x04001CBC RID: 7356
			public Vector3 velocity;

			// Token: 0x04001CBD RID: 7357
			public float distance;
		}
	}
}
